package com.sbio.udiapp.di;

import android.content.pm.PackageInfo;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;

import com.sbio.udiapp.BuildConfig;
import com.sbio.udiapp.net.api.ApiService;
import com.sbio.udiapp.util.DefaultSharedPreferencesUtil;
import com.sbio.udiapp.util.JsonUtil;
import com.sbio.udiapp.util.SharedPreferencesUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.components.ApplicationComponent;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

@InstallIn(ApplicationComponent.class)
@Module
public class NetWorkModule {

    private static final String Tag_OkHttpClient = "NetWorkModule.OkHttpClient";

    public static String baseUrl_dev = "https://pda-test.s-sbio.com";
    public static String dev_server_prefix = "dev-api";

//    public static String baseUrl_dev = "https://pda.s-sbio.com";
//    public static String dev_server_prefix = "prod-api";

    public static String baseUrl_prod = "https://pda.s-sbio.com";
    public static String prod_server_prefix = "prod-api";

    // 请求超时时间，单位：秒
    private static final int timeout = 100;

    /**
     * 创建OkHttpClient
     *
     * @return OkHttpClient
     */
    @Singleton
    @Provides
    public OkHttpClient provideOkHttpClient() {
        //http日志拦截器
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            //            @Override
            public void log(@NonNull String s) {
                Log.i(Tag_OkHttpClient, s);
            }
        })
                .setLevel(HttpLoggingInterceptor.Level.BODY);

        /**
         * 用户参数拦截器
         */
        Interceptor interceptor = new Interceptor() {
            @NonNull
            @Override
            public Response intercept(@NonNull Chain chain) throws IOException {
                Request original = chain.request();
                // 在这里可以修改原始请求，例如添加统一的参数
                // 这里假设要添加一个名为 "token" 的参数
                HttpUrl originalHttpUrl = original.url();
                String urlString = originalHttpUrl.toString();
                if (!urlString.startsWith(baseUrl_prod) && !urlString.startsWith(baseUrl_dev)) {
                    return chain.proceed(original);
                }
                // 判断是否为登录接口，这里假设登录接口的路径为 "/login"
//                if ("/login".equals(original.url().encodedPath())) {
//                    return chain.proceed(original); // 不添加参数，直接执行原始请求
//                }


                String jobNo = SharedPreferencesUtil.getString("username");

                Map<String, Object> param = new HashMap<>();
                param.put("osVersion", "android" + Build.VERSION.RELEASE);
                param.put("appVersion", BuildConfig.VERSION_NAME);
                param.put("operationClient", "android");
                if (!"/login2".equals(original.url().encodedPath())) {
                    String deviceNo = DefaultSharedPreferencesUtil.getDeviceNo();
                    if (Objects.equals(deviceNo, "")) {
                        throw new IOException("请先前往设置页面，填写设备编码");
                    }
                    param.put("jobNo", jobNo);
//                    return chain.proceed(original); // 不添加参数，直接执行原始请求
                } else {
                    param.put("tenantId", "000000");
                    param.put("clientId", "e5cd7e4891bf95d1d19206ce24a7b32e");
                    param.put("grantType", "password");
                }
                param.put("useDept", DefaultSharedPreferencesUtil.getUseDept());


                HttpUrl.Builder builder = originalHttpUrl.newBuilder();
                List<String> encodedPathSegments$okhttp = new ArrayList<>(builder.getEncodedPathSegments$okhttp());
                String prefix = dev_server_prefix;
                if (!BuildConfig.DEBUG) {
                    prefix = prod_server_prefix;
                }
                builder.setPathSegment(0, prefix);
                for (int i = 0; i < encodedPathSegments$okhttp.size() - 1; i++) {
                    builder.setPathSegment(i + 1, encodedPathSegments$okhttp.get(i));
                }
                builder.addEncodedPathSegment(encodedPathSegments$okhttp.get(encodedPathSegments$okhttp.size() - 1));
//                param.forEach((k, v) -> {
//                    builder.addQueryParameter(k, v.toString());
//                });
                String requestUniParam = originalHttpUrl.queryParameter("requestUniParam");
                if (requestUniParam == null) {
                    requestUniParam = "{}";
                }
                Map map = JsonUtil.parse(requestUniParam, Map.class);
                map.putAll(param);
                HttpUrl url = builder
                        .removeAllQueryParameters("requestUniParam")
                        .addQueryParameter("requestUniParam", JsonUtil.toJsonString(map))
                        .addQueryParameter("jobNo", jobNo)
                        .build();

                // 构建新的请求
                Request.Builder requestBuilder = original.newBuilder()
                        .url(url)
                        .addHeader("accept", "application/json");

                Request request = requestBuilder.build();

                return chain.proceed(request);
            }
        };
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
//                .sslSocketFactory(provideOkHttpClient().sslSocketFactory())
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(interceptor)
                .callTimeout(timeout, TimeUnit.SECONDS)
                .connectTimeout(50, TimeUnit.SECONDS)
                .readTimeout(50, TimeUnit.SECONDS)
                .writeTimeout(50, TimeUnit.SECONDS)
                .pingInterval(50, TimeUnit.SECONDS)
//                .followRedirects(false)
//                .followSslRedirects(false)
                .build();
        return okHttpClient;
    }

    /**
     * 创建 Retrofit
     *
     * @param okHttpClient
     * @return
     */
    @Singleton
    @Provides
    public Retrofit provideRetrofit(OkHttpClient okHttpClient) {
        String baseUrl = BuildConfig.DEBUG ? baseUrl_dev : baseUrl_prod;
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
    }

    /**
     * 创建 ApiService
     *
     * @param retrofit
     * @return
     */
    @Singleton
    @Provides
    ApiService provideApiService(Retrofit retrofit) {
        return retrofit.create(ApiService.class);
    }
}
